﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Dapper;
using Xejen.Database.Entities;

namespace Xejen.Database.Dapper
{
    /// <summary>
    /// 通过Dapper技术进行仓储访问
    /// </summary>
    /// <typeparam name="TDbContext">表示数据库上下文对象<see cref="IDbConnection"/></typeparam>
    /// <typeparam name="TEntity">表示要访问哪张表的实体映射</typeparam>
    /// <typeparam name="TPrimaryKey">表示要访问的表的主键Id的数据类型</typeparam>
    public class DapperRepository<TDbContext, TEntity, TPrimaryKey> : DapperRepositoryBase<TDbContext, TEntity, TPrimaryKey>, IRepositoryWithDbContext
        where TEntity : class, IEntity<TPrimaryKey>
        where TPrimaryKey : struct
        where TDbContext : IDbConnection
    {
        /// <summary>
        /// <inheritdoc cref="DapperRepository{TDbContext, TEntity, TPrimaryKey}" path="/summary"/>
        /// </summary>
        /// <param name="dbContextProvider"><inheritdoc cref="IDbContextProvider{TDbContext}" path="/summary"/></param>
        public DapperRepository(IDbContextProvider<TDbContext> dbContextProvider) : base(dbContextProvider)
        {
           
        }

        /// <inheritdoc/>
        public override TEntity Insert(string sql, TEntity entity)
        {
            //var query = "INSERT INTO Users (Name, Age) VALUES (@Name, @Age); SELECT CAST(SCOPE_IDENTITY() as int)";
            var result = Connection.Execute(sql, entity);
            if (result > 0)
            {
                entity.Id = Connection.ExecuteScalar<TPrimaryKey>("SELECT last_insert_rowid();");
            }
            return entity;
        }

        /// <inheritdoc/>
        public override async Task<TEntity> InsertAsync(string sql, TEntity entity)
        {
            //var query = "INSERT INTO Users (Name, Age) VALUES (@Name, @Age); SELECT CAST(SCOPE_IDENTITY() as int)";
            var result = await Connection.ExecuteAsync(sql, entity);
            if (result > 0)
            {
                entity.Id = await Connection.ExecuteScalarAsync<TPrimaryKey>("SELECT last_insert_rowid();");
            }
            return entity;
        }
    }
}
